package com.yiboshi.rehrs.util;

import cn.hutool.core.thread.ThreadUtil;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;

import java.io.Serializable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

/**
 * @author jack 2022/9/27
 */
public class CacheUtils {

    public final static ConcurrentHashMap<String, Cache<String, Object>> CONCURRENT_HASH_MAP = new ConcurrentHashMap<>();


    public final static Cache<String, Object> builder(Integer seconds) {
        String key = seconds + "s";
        Cache<String, Object> cache = CONCURRENT_HASH_MAP.get(key);
        if (cache == null) {
            cache = Caffeine.newBuilder()
                    .expireAfterWrite(seconds, TimeUnit.SECONDS)
                    .maximumSize(1000)
                    .initialCapacity(16)
                    .build();
            CONCURRENT_HASH_MAP.putIfAbsent(key, cache);
            cache = CONCURRENT_HASH_MAP.get(key);
        }
        return cache;
    }


    public static <T> T get(Integer seconds, Serializable key) {
        String cacheKey = key.toString();
        return (T) builder(seconds).getIfPresent(cacheKey);
    }



    public static <T> void delAll(Integer seconds) {
        builder(seconds).invalidateAll();

    }

    public static void main(String[] args) {

        Object name = get(5, "name");
        System.out.println(name);

        ThreadUtil.sleep(3000);
        name = get(5, "name");
        System.out.println(name);

    }


    //10分钟
    private final static Cache<String, Object> GLOBAL_CACHE_10MIN = Caffeine.newBuilder()
            .expireAfterWrite(10, TimeUnit.MINUTES)
            .maximumSize(2000)
            .initialCapacity(20)
            .build();

    //10个小时
    private final static Cache<String, Object> GLOBAL_CACHE = Caffeine.newBuilder()
            .expireAfterWrite(10, TimeUnit.HOURS)
            .maximumSize(2000)
            .initialCapacity(20)
            .build();


    public static void putByCache10Min(Serializable key, Object s) {
        if (s == null) {
            GLOBAL_CACHE_10MIN.invalidate(key);
            return;
        }
        String newKey = getCacheKey(key, s.getClass());
        GLOBAL_CACHE_10MIN.put(newKey, s);
    }

    public static <T> T getByCache10Min(Serializable key, Class<T> clazz) {
        String cacheKey = getCacheKey(key, clazz);
        return (T) GLOBAL_CACHE_10MIN.getIfPresent(cacheKey);
    }

    public static <T> void delByCache10Min() {
        GLOBAL_CACHE_10MIN.invalidateAll();

    }
    public static <T> void delByCache10Min(Serializable key, Class<T> clazz) {
        String newKey = getCacheKey(key, clazz);
        GLOBAL_CACHE_10MIN.invalidate(newKey);

    }


    public static <T> T getByCache10Hour(Serializable key, Class<T> clazz) {
        String cacheKey = getCacheKey(key, clazz);
        return (T) GLOBAL_CACHE.getIfPresent(cacheKey);
    }

    public static void putByCache10Hour(Serializable key, Object s) {
        if (s == null) {
            //GLOBAL_CACHE.invalidate(key);
            return;
        }
        String newKey = getCacheKey(key, s.getClass());
        GLOBAL_CACHE.put(newKey, s);
    }

    public static <T> void delByCache10Hour(Serializable key, Class<T> clazz) {
        String newKey = getCacheKey(key, clazz);
        GLOBAL_CACHE.invalidate(newKey);

    }

    private static String getCacheKey(Serializable key, Class<?> aClass) {
        return aClass.getName() + "-" + key.toString();
    }
}
